package com.gzg.userservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gzg.userservice.client.PermissionClient;
import com.gzg.userservice.domain.dto.LoginDTO;
import com.gzg.userservice.domain.dto.PageDTO;
import com.gzg.userservice.domain.po.Log;
import com.gzg.userservice.domain.po.User;
import com.gzg.userservice.domain.vo.LoginVO;
import com.gzg.userservice.domain.vo.PageVO;
import com.gzg.userservice.domain.vo.Result;
import com.gzg.userservice.mapper.UserMapper;
import com.gzg.userservice.service.IUserService;
import com.gzg.userservice.utils.UserContext;
import com.gzg.userservice.utils.jwtUtils;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper , User> implements IUserService {

    private final PermissionClient  permissionClient;
    private final jwtUtils jwtUtils;
    private final UserMapper userMapper;
    private final RabbitTemplate rabbitTemplate;
    @Override
    @GlobalTransactional
    public Result register(User user) {
        //校验用户信息
        if(lambdaQuery().eq(User::getPhone,user.getPhone()).count() >= 1){
            return Result.fail("手机号已注册");
        }
        if(lambdaQuery().eq(User::getUsername , user.getUsername()).count() >= 1){
            return Result.fail("用户名已存在");
        }
        //设置时间
        user.setGmtCreate(LocalDateTime.now());
        //雪花算法生成Userid
        Snowflake snowflake = new Snowflake(1, 1);
        long userId = snowflake.nextId();
        Random random = new Random();
        userId = userId * 10 + random.nextInt(9)+1;
        user.setUserId(userId);
        //TODO分布式事务
        if (save(user)) {
            //rpc 绑定默认角色
            permissionClient.bindDefaultRole(userId);
            //封装Log类
            Log log = new Log();
            log.setUserId(userId);
            log.setAction("save_user");
            log.setIp(UserContext.getIp());
            log.setDetail(user.toString());
            //TODO 发送异步消息 添加日志
            String exName = "simple.fanout";
            rabbitTemplate.convertAndSend(exName,"",log);
            return Result.ok();
        }
        return Result.fail("注册失败");
    }

    @Override
    public Result login(LoginDTO loginDTO) {
        User user = lambdaQuery().eq(User::getUsername,loginDTO.getUsername()).eq(User::getPassword,loginDTO.getPassword()).one();
        if(user==null){
            return Result.fail("用户名或密码错误");
        }
        LoginVO loginVO = new LoginVO();
        BeanUtil.copyProperties(user,loginVO);
        String token = jwtUtils.genToken(loginVO.getUsername(), loginVO.getUserId());
        loginVO.setJwtToken(token);
        return Result.ok(loginVO);
    }

    @Override
    public Result queryUsersPage(PageDTO pageDTO) {
        if (pageDTO == null || pageDTO.getPageNum() < 1 || pageDTO.getPageSize() < 1){
            log.info("分页参数错误");
            return Result.fail("分页参数错误");
        }
        int total , pageNum ;
        PageVO pageVO = new PageVO();
        int start = (pageDTO.getPageNum()-1)*pageDTO.getPageSize();
        //获取当前角色的角色码
        int userRoleCode = permissionClient.getUserRoleId(UserContext.getUser());
        switch (userRoleCode){
            case 1:
               List<User>  users= userMapper.queryAllUsers(start, pageDTO.getPageSize());
                total = userMapper.queryAllUsersCount();
                pageNum = total%pageDTO.getPageSize()==0?total/pageDTO.getPageSize():total/pageDTO.getPageSize()+1;
                pageVO = getPageVO(total,pageNum,users);
                return Result.ok(pageVO);
            case 3:
                List<Long> Ids = permissionClient.getNormalUserIds();
                List<User>  norUsers = userMapper.queryUsersByIds(Ids,start,pageDTO.getPageSize());
                total = Ids.size();
                pageNum = total%pageDTO.getPageSize()==0?total/pageDTO.getPageSize():total/pageDTO.getPageSize()+1;
                 pageVO = getPageVO(total, pageNum, norUsers);
                return Result.ok(pageVO);
            case 2:
                Long userId = UserContext.getUser();
                User user = lambdaQuery().eq(User::getUserId, userId).one();
                List<User> one = new ArrayList<User>();
                one.add(user);
                pageVO = getPageVO(1, 1, one);
                return Result.ok(pageVO);
            default:
                return Result.fail("权限错误");
        }
    }

    @Override
    public Result queryUserById(Long id) {
        //获取当前角色的角色码
        int userRoleCode = permissionClient.getUserRoleId(UserContext.getUser());
        User user = new User();
        switch (userRoleCode){
            case 1:
                user = lambdaQuery().eq(User::getUserId, id).one();
                return Result.ok(user);
            case 3:
                int queriedUId = permissionClient.getUserRoleId(id);
                if(queriedUId != 2){
                    return Result.fail("不能越权访问");
                }
                user = lambdaQuery().eq(User::getUserId, id).one();
                return Result.ok(user);
            case 2:
                if(!id.equals(UserContext.getUser())){
                    return Result.fail("不能越权访问");
                }
                user = lambdaQuery().eq(User::getUserId, id).one();
                return Result.ok(user);
            default:
                return Result.fail("权限错误");

        }
    }

    @Override
    public Result updateUser(User user) {
        int userRoleCode = permissionClient.getUserRoleId(UserContext.getUser());
        int queriedUId = permissionClient.getUserRoleId(user.getUserId());
        boolean update;
        switch (userRoleCode){
            case 1:
                update = userMapper.updateBUseryId(user);
                return Result.ok(update);
            case 3:
                if(queriedUId == 1 ||(queriedUId == 3 && queriedUId != UserContext.getUser())){
                    return Result.fail("不能越权访问");
                }
                update = userMapper.updateBUseryId(user);
                return Result.ok(update);
            case 2:
                if(queriedUId != UserContext.getUser()){
                    return Result.fail("不能越权访问");
                }
                update = userMapper.updateBUseryId(user);
                return Result.ok(update);
            default:
                return Result.fail("没有这个权限");
        }
    }

    @Override
    public Result resetPassword(User user) {
        int userRoleCode = permissionClient.getUserRoleId(UserContext.getUser());
        int queriedUId = permissionClient.getUserRoleId(user.getUserId());
        boolean update;
        switch (userRoleCode){
            case 1:
                update = lambdaUpdate().eq(User::getUserId, user.getUserId()).set(User::getPassword, "000000").update();
                return Result.ok(update);
            case 3:
                if(queriedUId == 1 ||(queriedUId == 3 && queriedUId != UserContext.getUser())){
                    return Result.fail("不能越权访问");
                }
                update = lambdaUpdate().eq(User::getUserId, user.getUserId()).set(User::getPassword, "000000").update();
                return Result.ok(update);
            case 2:
                if(queriedUId != UserContext.getUser()){
                    return Result.fail("不能越权访问");
                }
                update = lambdaUpdate().eq(User::getUserId, user.getUserId()).set(User::getPassword, "000000").update();
                return Result.ok(update);
            default:
                return Result.fail("没有这个权限");
        }
    }

    private static PageVO getPageVO(int total,int pageNum , List< User> users) {
        PageVO pageVO = new PageVO();
        pageVO.setTotal(total);
        pageVO.setPageNum(pageNum);
        pageVO.setList(users);
        return pageVO;
    }
}
